package com.sf.fy.uav.applet.operate.controller;

import com.sf.fy.uav.applet.config.DelayQueue;
import com.sf.fy.uav.common.utils.AreaOverlapCheckUtils;
import com.sf.fy.uav.applet.utils.DistanceHelper;
import com.sf.fy.uav.common.enums.ServicePrefixEnum;
import com.sf.fy.uav.common.response.TtTesTerminalRangeCoordinateResponse;
import com.sf.fy.uav.common.response.TtTesTerminalRangeResponse;
import com.sf.fy.uav.common.response.TtTesTerminalResponse;
import com.sf.fy.uav.common.utils.*;
import com.sf.fy.uav.controller.AirportInfoRest;
import com.sf.fy.uav.controller.TtTesTerminalRangeController;
import com.sf.fy.uav.controller.TtTesTerminalRangeCoordinateController;
import com.sf.fy.uav.entity.AirportInfo;
import com.sf.fy.uav.entity.TtTesTerminalRange;
import com.sf.fy.uav.entity.TtTesTerminalRangeCoordinate;
import com.sf.fy.uav.rest.controller.TtTesTerminalRest;
import com.sf.fy.uav.rest.entity.TtTesTerminal;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 航站信息，用于维护要展示的航站列表数据 前端控制器
 * </p>
 *
 * @author LTQ
 * @since 2024-02-20
 */
@RestController
@RequestMapping("/home/airport/")
public class AirportInfoController {

    @Autowired
    private AirportInfoRest airportInfoRest;

    @Autowired
    private TtTesTerminalRest ttTesTerminalRest;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DelayQueue delayQueue;

    @Autowired
    private TtTesTerminalRangeController ttTesTerminalRangeController;

    @Autowired
    private TtTesTerminalRangeCoordinateController ttTesTerminalRangeCoordinateController;

    @GetMapping("get-list")
    @Operation(tags = "获取航站列表", description = "获取航站列表")
    public Rs<List<AirportInfo>> getList() {
        return Rs.success(airportInfoRest.getList());
    }


    @GetMapping("list")
    @Operation(tags = "获取航站列表", description = "获取航站列表")
    @Transactional
    @Retryable(backoff = @Backoff(delay = 1000))
    public Rs<List<TtTesTerminalResponse>> list() throws Exception {
        List<TtTesTerminalResponse> ttTesTerminalResponses = new ArrayList<>();
        List<TtTesTerminal> ttTesTerminals = ttTesTerminalRest.getTtTesTerminals();
        if (!CollectionUtils.isEmpty(ttTesTerminals)) {
            List<Long> ttTesTerminalsId = ttTesTerminals.stream().map(ttTesTerminal -> ttTesTerminal.getId()).collect(Collectors.toList());
            List<TtTesTerminalRange> ttTesTerminalRanges = ttTesTerminalRangeController.getByTerminalId(ttTesTerminalsId);
            if (!CollectionUtils.isEmpty(ttTesTerminalRanges)) {
                List<Long> ttTesTerminalRangesId = ttTesTerminalRanges.stream().map(ttTesTerminalRange -> ttTesTerminalRange.getId()).collect(Collectors.toList());
                List<TtTesTerminalRangeCoordinate> ttTesTerminalRangeCoordinates = ttTesTerminalRangeCoordinateController.getByTerminalIdAndRangeId(ttTesTerminalsId, ttTesTerminalRangesId);
                for (TtTesTerminal ttTesTerminal : ttTesTerminals) {
                    TtTesTerminalResponse ttTesTerminalResponse = BeanUtil.copyProperties(ttTesTerminal, TtTesTerminalResponse.class);
                    String outShortName = ttTesTerminal.getOutShortName();
                    if (!ObjectUtils.isEmpty(outShortName)) {
                        ttTesTerminalResponse.setName(outShortName);
                    }
                    List<TtTesTerminalRange> sonTtTesTerminalRanges = ttTesTerminalRanges.stream().filter(ttTesTerminalRange -> ttTesTerminalRange.getTerminalId().equals(ttTesTerminal.getId())).collect(Collectors.toList());

                    List<TtTesTerminalRangeResponse> ttTesTerminalRangeResponses = new ArrayList<>();
                    for (TtTesTerminalRange ttTesTerminalRange : sonTtTesTerminalRanges) {
                        TtTesTerminalRangeResponse ttTesTerminalRangeResponse = BeanUtil.copyProperties(ttTesTerminalRange, TtTesTerminalRangeResponse.class);
                        List<TtTesTerminalRangeCoordinate> sonTtTesTerminalRangeCoordinates = ttTesTerminalRangeCoordinates.stream().filter(ttTesTerminalRangeCoordinate -> ttTesTerminalRangeCoordinate.getRangeId().equals(ttTesTerminalRange.getId()) && ttTesTerminalRangeCoordinate.getTerminalId().equals(ttTesTerminal.getId())).collect(Collectors.toList());
                        List<TtTesTerminalRangeCoordinateResponse> ttTesTerminalRangeCoordinateResponses = BeanUtil.copyProperties(sonTtTesTerminalRangeCoordinates, TtTesTerminalRangeCoordinateResponse.class);

                        for (TtTesTerminalRangeCoordinateResponse tesTerminalRangeCoordinateResponse : ttTesTerminalRangeCoordinateResponses) {
                            String longitude = tesTerminalRangeCoordinateResponse.getLongitude();
                            String latitude = tesTerminalRangeCoordinateResponse.getLatitude();
                            double[] doubles = GpsUtil.gps84_To_Gcj02(Double.valueOf(latitude), Double.valueOf(longitude));
                            tesTerminalRangeCoordinateResponse.setLatitude(new BigDecimal(String.valueOf(doubles[0])).setScale(7, RoundingMode.HALF_UP).toString());
                            tesTerminalRangeCoordinateResponse.setLongitude(new BigDecimal(String.valueOf(doubles[1])).setScale(7, RoundingMode.HALF_UP).toString());

                        }

                        ttTesTerminalRangeResponse.setTtTesTerminalRangeCoordinateResponses(ttTesTerminalRangeCoordinateResponses);
                        ttTesTerminalRangeResponses.add(ttTesTerminalRangeResponse);
                    }

                    ttTesTerminalResponse.setTtTesTerminalRangeResponses(ttTesTerminalRangeResponses);
                    String longitude = ttTesTerminal.getLongitude();
                    String latitude = ttTesTerminal.getLatitude();
                    double[] doubles = GpsUtil.gps84_To_Gcj02(Double.valueOf(latitude), Double.valueOf(longitude));
                    ttTesTerminalResponse.setLatitude(new BigDecimal(String.valueOf(doubles[0])).setScale(7, RoundingMode.HALF_UP).toString());
                    ttTesTerminalResponse.setLongitude(new BigDecimal(String.valueOf(doubles[1])).setScale(7, RoundingMode.HALF_UP).toString());
                    ttTesTerminalResponses.add(ttTesTerminalResponse);
                }
            } else {
                throw new Exception("同步未完成");
            }
        } else {
            throw new Exception("同步未完成");
        }
        return Rs.success(ttTesTerminalResponses);
    }

    /**
     * 判断点是否在区域内
     *
     * @param longitude
     * @param latitude
     * @return
     */
    @GetMapping("is-point-in-polygon")
    Rs<String> isPointInPolygon(@RequestParam double longitude, @RequestParam double latitude) {
        String uuid = UUID.randomUUID().toString();
        AreaOverlapCheckUtils.Location targetLocation = new AreaOverlapCheckUtils.Location(longitude, latitude);
        List<TtTesTerminal> ttTesTerminals = ttTesTerminalRest.getTtTesTerminals();
        if (!CollectionUtils.isEmpty(ttTesTerminals)) {
            List<Long> ttTesTerminalsId = ttTesTerminals.stream().map(ttTesTerminal -> ttTesTerminal.getId()).collect(Collectors.toList());
            List<TtTesTerminalRange> ttTesTerminalRanges = ttTesTerminalRangeController.getByTerminalId(ttTesTerminalsId);
            if (!CollectionUtils.isEmpty(ttTesTerminalRanges)) {
                List<Long> ttTesTerminalRangesId = ttTesTerminalRanges.stream().map(ttTesTerminalRange -> ttTesTerminalRange.getId()).collect(Collectors.toList());
                List<TtTesTerminalRangeCoordinate> ttTesTerminalRangeCoordinates = ttTesTerminalRangeCoordinateController.getByTerminalIdAndRangeId(ttTesTerminalsId, ttTesTerminalRangesId);
                for (TtTesTerminal ttTesTerminal : ttTesTerminals) {
                    for (TtTesTerminalRange ttTesTerminalRange : ttTesTerminalRanges) {
                        List<TtTesTerminalRangeCoordinate> sonTtTesTerminalRangeCoordinates = ttTesTerminalRangeCoordinates.stream().filter(ttTesTerminalRangeCoordinate -> ttTesTerminalRangeCoordinate.getRangeId().equals(ttTesTerminalRange.getId()) && ttTesTerminalRangeCoordinate.getTerminalId().equals(ttTesTerminal.getId())).collect(Collectors.toList());
                        List<AreaOverlapCheckUtils.Location> locationList2 = new ArrayList<>();
                        sonTtTesTerminalRangeCoordinates = sonTtTesTerminalRangeCoordinates.stream().sorted(Comparator.comparingInt(TtTesTerminalRangeCoordinate::getOrderNo)).collect(Collectors.toList());
                        for (TtTesTerminalRangeCoordinate ttTesTerminalRangeCoordinate : sonTtTesTerminalRangeCoordinates) {
                            AreaOverlapCheckUtils.Location location = new AreaOverlapCheckUtils.Location(Double.valueOf(ttTesTerminalRangeCoordinate.getLongitude()), Double.valueOf(ttTesTerminalRangeCoordinate.getLatitude()));
                            locationList2.add(location);
                        }
                        if (!CollectionUtils.isEmpty(locationList2)) {
                            Byte shape = ttTesTerminalRange.getShape();
                            if (shape == 1) {
                                //多边形
                                if (AreaOverlapCheckUtils.isPointInPolygon(targetLocation, locationList2)) {
                                    delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.RECORD_AIR_PORT + uuid + "_" + String.valueOf(longitude) + "_" + String.valueOf(latitude), 0L);
                                    return Rs.success(uuid);
                                }
                            } else if (shape == 2) {
                                //圆形
                                if (!CollectionUtils.isEmpty(sonTtTesTerminalRangeCoordinates)) {
                                    TtTesTerminalRangeCoordinate ttTesTerminalRangeCoordinate = sonTtTesTerminalRangeCoordinates.get(0);
                                    Object radius = ttTesTerminalRangeCoordinate.getRadius();
                                    String centerOfCircleLatitude = ttTesTerminalRangeCoordinate.getLatitude();
                                    String centerOfCircleLongitude = ttTesTerminalRangeCoordinate.getLongitude();
                                    //圆形
                                    double distance = DistanceHelper.getDistance(Double.valueOf(centerOfCircleLatitude), Double.valueOf(centerOfCircleLongitude), latitude, longitude);
                                    if (distance * 1000 < (Double) radius) {
                                        delayQueue.pushQueue(ServicePrefixEnum.SAME_CITY + RedisPrefixKey.RECORD_AIR_PORT + uuid + "_" + String.valueOf(longitude) + "_" + String.valueOf(latitude), 0L);
                                        return Rs.success(uuid);
                                    }
                                }

                            }
                        }
                    }
                }
            }
        }
        return Rs.success(null);
    }

}